package org.example.netty.zk;

import io.netty.util.CharsetUtil;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.utils.CloseableUtils;
import org.apache.zookeeper.AsyncCallback;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.data.Stat;
import org.example.zk.ClientFactory;
import org.junit.Test;

import java.nio.charset.StandardCharsets;
import java.util.List;

public class Zktest {

    private static final String ZOOKEEPER_ADDRESS = "localhost:2181";

    @Test
    public void createNode() {
        CuratorFramework client = ClientFactory.createSimple(ZOOKEEPER_ADDRESS);

        try {
            // TODO 启动客户端实例，连接服务器
            client.start();

            String content = "helloworld";
            byte[] data = content.getBytes(StandardCharsets.UTF_8);
            String nodePath = "/test/CRUD/node-1";
            client.create()
                    .creatingParentsIfNeeded()
                    .withMode(CreateMode.PERSISTENT)
                    .forPath(nodePath, data);
        }
        catch (KeeperException.NodeExistsException e) {
            // TODO 节点已经存在
        }
        catch (Exception e) {
            e.printStackTrace();
        } finally {
            CloseableUtils.closeQuietly(client);
        }
    }

    @Test
    public void createSeqNode() {
        CuratorFramework client = ClientFactory.createSimple(ZOOKEEPER_ADDRESS);

        try {
            // TODO 启动客户端实例，连接服务器
            client.start();

            String content = "helloworld";
            byte[] data = content.getBytes(StandardCharsets.UTF_8);
            String nodePath = "/test/CRUD/node-";
            String path = client.create()
                    .creatingParentsIfNeeded()
                    // TODO 持久化顺序节点
                    .withMode(CreateMode.PERSISTENT_SEQUENTIAL)
                    .forPath(nodePath, data);
            System.out.println("path = " + path);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            CloseableUtils.closeQuietly(client);
        }
    }

    @Test
    public void createTempNode() {
        CuratorFramework client = ClientFactory.createSimple(ZOOKEEPER_ADDRESS);

        try {
            // TODO 启动客户端实例，连接服务器
            client.start();

            String content = "helloworld";
            byte[] data = content.getBytes(StandardCharsets.UTF_8);
            String nodePath = "/test/CRUD/node-";
            client.create()
                    .creatingParentsIfNeeded()
                    // TODO 临时节点，10秒以后自动删除
                    .withMode(CreateMode.EPHEMERAL)
                    .forPath(nodePath, data);

            Thread.sleep(5000);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            CloseableUtils.closeQuietly(client);
        }
    }

    /**
     * 读取节点
     */
    @Test
    public void readNode() {
        CuratorFramework client = ClientFactory.createSimple(ZOOKEEPER_ADDRESS);

        try {
            // TODO 启动客户端实例，连接服务器
            client.start();

            // TODO读取某个节点的数据
            String path = "/test/CRUD/node-0000000004";
            Stat stat = client.checkExists().forPath(path);
            if (stat != null) {
                byte[] bytes = client.getData().forPath(path);
                System.out.println(String.format("%s = %s", path, new String(bytes)));
            }

            // TODO 获取子节点，获取下一层节点的名字
            List<String> list = client.getChildren().forPath("/test");
            list.forEach(item -> {
                System.out.println(item);
            });
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            CloseableUtils.closeQuietly(client);
        }
    }

    /**
     * 同步更新
     */
    @Test
    public void updateNode() {
        CuratorFramework client = ClientFactory.createSimple(ZOOKEEPER_ADDRESS);

        try {
            // TODO 启动客户端实例，连接服务器
            client.start();

            // TODO 读取某个节点的数据
            String newContent = "hello, zookeeper";
            String path = "/test/CRUD/node-0000000004";
            Stat stat = client.checkExists().forPath(path);
            if (stat != null) {
                client.setData().forPath(path, newContent.getBytes(CharsetUtil.UTF_8));
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            CloseableUtils.closeQuietly(client);
        }
    }

    /**
     * 异步更新
     */
    @Test
    public void updateAsyncNode() {
        CuratorFramework client = ClientFactory.createSimple(ZOOKEEPER_ADDRESS);

        AsyncCallback.StringCallback callback = new AsyncCallback.StringCallback() {
            @Override
            public void processResult(int i, String s, Object o, String s1) {
                System.out.println(
                        "i = " + i + " | " +
                                "s = " + s + " | " +
                                "o = " + o + " | " +
                                "s1 = " + s1
                );
            }
        };

        try {
            // TODO 启动客户端实例，连接服务器
            client.start();

            // TODO 读取某个节点的数据
            String newContent = "hello, zookeeper333";
            String path = "/test/CRUD/node-0000000004";
            Stat stat = client.checkExists().forPath(path);
            if (stat != null) {
                client
                        .setData()
                        .inBackground(callback)
                        .forPath(path, newContent.getBytes(CharsetUtil.UTF_8));
            }

            Thread.sleep(10000);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            CloseableUtils.closeQuietly(client);
        }
    }
}
